import com.fasterxml.jackson.annotation.JsonProperty
{{#kotlinx_serialization}}
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
{{/kotlinx_serialization}}

/**
 * {{{description}}}
 *
 * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
 */
{{#kotlinx_serialization}}@Serializable{{/kotlinx_serialization}}
{{>additionalModelTypeAnnotations}}
{{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{classname}}(val value: {{{dataType}}}) {
{{#allowableValues}}{{#enumVars}}

    {{#enumDescription}}
    /**
    * {{.}}
    */
    {{/enumDescription}}
    @JsonProperty(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}})
    {{#kotlinx_serialization}}
    @SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}})
    {{/kotlinx_serialization}}
    {{#isArray}}
    {{#isList}}
    {{&name}}(listOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}}
    {{/isList}}
    {{^isList}}
    {{&name}}(arrayOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}}
    {{/isList}}
    {{/isArray}}
    {{^isArray}}
    {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
    {{/isArray}}
{{/enumVars}}{{/allowableValues}}
    /**
     * Override toString() to avoid using the enum variable name as the value, and instead use
     * the actual value defined in the API spec file.
     *
     * This solves a problem when the variable name and its value are different, and ensures that
     * the client sends the correct enum values to the server always.
     */
    override fun toString(): String = value{{^isString}}.toString(){{/isString}}

    companion object {
        /**
         * Converts the provided [data] to a [String] on success, null otherwise.
         */
        fun encode(data: Any?): kotlin.String? = if (data is {{classname}}) "$data" else null

        /**
         * Returns a valid [{{classname}}] for [data], null otherwise.
         */
        @OptIn(ExperimentalStdlibApi::class)
        fun decode(data: Any?): {{classname}}? = data?.let {
          val normalizedData = "$it".lowercase()
          values().firstOrNull { value ->
            it == value || normalizedData == "$value".lowercase()
          }
        }
    }
}
